
#include "TimerManage.hpp"
#include <iostream>
using namespace std;

namespace zhb
{
    TimerMap::TimerMap()
        : m_epollfd(-1), m_stop(false)
    {
        m_events.resize(eventsize);
    }

    TimerMap::~TimerMap()
    {
        set_stop();
    }

    bool TimerMap::init(int timeout)
    {
        bool ret = false;
        m_epollfd = ::epoll_create1(EPOLL_CLOEXEC);
        if (m_epollfd > 0)
        {
            try
            {
                m_workerThread = std::thread(&TimerMap::loop, this, timeout);
                ret = true;
            }
            catch (const std::exception &e)
            {
                std::cerr << e.what() << '\n';
                close(m_epollfd);
                m_epollfd = -1;
            }
        }
        return ret;
    }

    bool TimerMap::add_timer(Timer &tv)
    {
        struct epoll_event ev;
        ev.data.fd = tv.get_TimerId();
        ev.events = EPOLLIN;
        if (epoll_ctl(m_epollfd, EPOLL_CTL_ADD, tv.get_TimerId(), &ev) < 0)
        {
            return false;
        }
        m_timers[tv.get_TimerId()] = std::move(tv);
        return true;
    }

    void TimerMap::remove_timer(Timer &tv) {}

    bool TimerMap::loop(int timeout)
    {
        while (!m_stop)
        {
            int n = epoll_wait(m_epollfd, m_events.data(), m_events.size(), timeout);
            for (int i = 0; i < n; i++)
            {
                int fd = m_events[i].data.fd;
                auto it = m_timers.find(fd);
                if (it != m_timers.end())
                {
                    Timer &tv = it->second;
                    tv.handle_event();
                }
            }
            if(n>=m_events.size()){
                m_events.resize(m_events.size()*2);
            }
        }
        return true;
    }

    void TimerMap::set_stop() {
        m_stop=true;
        if(m_workerThread.joinable()){
            m_workerThread.join();
        }
        close(m_epollfd);
        m_epollfd=-1;

    }
}